package com.nineclock.document.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nineclock.common.entity.PageResult;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.CountUtil;
import com.nineclock.document.dto.DocFileDto;
import com.nineclock.document.dto.DocFileHistoryDto;
import com.nineclock.document.dto.DocFolderDto;
import com.nineclock.document.dto.DocumentDto;
import com.nineclock.document.dto.*;
import com.nineclock.document.enums.DocumentPermissionEnum;
import com.nineclock.document.mapper.DocCollaborationsMapper;
import com.nineclock.document.mapper.DocFileHistoryMapper;
import com.nineclock.document.mapper.DocFileMapper;
import com.nineclock.document.mapper.DocFolderMapper;
import com.nineclock.document.pojo.DocCollaborations;
import com.nineclock.document.pojo.DocFile;
import com.nineclock.document.pojo.DocFileHistory;
import com.nineclock.document.pojo.DocFolder;
import com.nineclock.document.service.AppDocumentService;
import com.nineclock.system.dto.SysCompanyUserDTO;
import com.nineclock.system.feign.SysUserFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 * @Version 1.0
 */
@Service
public class AppDocumentServiceImpl implements AppDocumentService {


    @Override
    public DocumentDto queryFolderAndFile(Long parentFolderId) {
        DocumentDto documentDto = new DocumentDto();

        //查询文件夹列表
        List<DocFolderDto> docFolderDtoList = this.queryFolderList(parentFolderId);
        //文件文件列表
        List<DocFileDto> docFileDtoList = this.queryFileList(parentFolderId);

        //组合数据
        documentDto.setFolders(docFolderDtoList);
        documentDto.setFiles(docFileDtoList);

        return documentDto;
    }

    @Override
    public void insertFolder(DocFolderDto docFolderDto) {
        if (docFolderDto == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //转换dockFolder对象
        DocFolder docFolder = BeanHelper.copyProperties(docFolderDto, DocFolder.class);
        //设置其他的参数
        docFolder.setCompanyId(CurrentUserHolder.get().getCompanyId());
        docFolder.setOrderNum(0);
        docFolder.setCreateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFolder.setCreateTime(new Date());
        docFolder.setStatus((short) 1);

        //保存到数据库
        folderMapper.insert(docFolder);

    }

    @Autowired
    DocFileHistoryMapper docFileHistoryMapper;

    @Override
    public void insertFile(DocFileDto docFileDto) {
        if (docFileDto == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        DocFile docFile = BeanHelper.copyProperties(docFileDto, DocFile.class);
        docFile.setCreateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFile.setCreateTime(new Date());
        docFile.setType((short) 1);
        docFile.setPermission(DocumentPermissionEnum.PRIVATE_READ_WRITE.getPermission());
        docFile.setCompanyId(CurrentUserHolder.get().getCompanyId());
        docFile.setStatus((short) 1);
        //使用工具类获取文档大小
        try {
            docFile.setFileSize(CountUtil.getSize(docFile.getContent().getBytes("utf-8").length));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        docFile.setFileSize(docFileDto.getContent().getBytes().toString());
        docFile.setStatus((short) 1);
        //保存文档信息
        docFileMapper.insert(docFile);

        //保存文档历史信息
        DocFileHistory docFileHistory = new DocFileHistory();
        docFileHistory.setFileId(docFile.getId());
        docFileHistory.setFileName(docFile.getName());
        docFileHistory.setOperateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFileHistory.setOperateTime(new Date());
        docFileHistory.setIsCreate((short) 1);
        docFileHistory.setContent(docFile.getContent());

        docFileHistoryMapper.insert(docFileHistory);
    }

    @Override
    public DocFileDto getFileByFileId(Long fileId) {
        DocFile docFile = docFileMapper.selectById(fileId);
        if (docFile == null) {
            throw new NcException(ResponseEnum.FILE_NOT_FOUND);
        }
        return BeanHelper.copyProperties(docFile, DocFileDto.class);
    }

    @Override
    public List<DocFileHistoryDto> getHistoryByFileId(Long fileId) {
        if (fileId == null) {
            throw new NcException(ResponseEnum.DATA_NOT_EXISTS);
        }
        List<DocFileHistoryDto> resultList = new ArrayList<>();

        LambdaQueryWrapper<DocFileHistory> docFileHistoryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        docFileHistoryLambdaQueryWrapper.eq(DocFileHistory::getFileId, fileId);
        List<DocFileHistory> historyList = docFileHistoryMapper.selectList(docFileHistoryLambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(historyList)) {
            for (DocFileHistory history : historyList) {
                DocFileHistoryDto docFileHistoryDto = new DocFileHistoryDto();
                docFileHistoryDto.setFileId(fileId);
                docFileHistoryDto.setFileName(history.getFileName());
                docFileHistoryDto.setIsCreate(history.getIsCreate());
                docFileHistoryDto.setOperateUserId(history.getOperateUserId());
                docFileHistoryDto.setOperateTime(history.getOperateTime());
                docFileHistoryDto.setContent(history.getContent());
                resultList.add(docFileHistoryDto);
            }

        }
        return resultList;
    }


    @Override
    public void getDocFileIdAndStatus(Long id, Short status) {

        //LambdaUpdateWrapper<DocFile> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        //lambdaUpdateWrapper.eq(DocFile::getId, id).eq(DocFile::getStatus, status);
        //DocFile docFile = new DocFile();
        //docFile.setId(id);
        //docFile.setStatus(status);
        //docFileMapper.update(docFile, lambdaUpdaocteWrapper);

        DocFile docFile = docFileMapper.selectById(id);
        docFile.setStatus(status);
        docFileMapper.updateById(docFile);
    }

    @Override
    public void updateFile(DocFileDto docFileDto) {
        if (docFileDto == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        DocFile docFile = docFileMapper.selectById(docFileDto.getId());

        docFile.setContent(docFileDto.getContent());
        docFile.setName(docFileDto.getName());
        docFile.setUpdateUserId(CurrentUserHolder.get().getCompanyUserId());
        //使用工具类获取文档大小
        try {
            docFile.setFileSize(CountUtil.getSize(docFile.getContent().getBytes("utf-8").length));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        docFileMapper.updateById(docFile);
    }

    @Autowired
    DocCollaborationsMapper docCollaborationsMapper;

    @Override
    public PageResult<DocumentUserDTO> pagingCollaborations(Long id, Long page, Long pageSize) {
        PageResult<DocumentUserDTO> documentUserDTOPageResult = new PageResult<>();
        if (page != null && pageSize != null) {
            LambdaQueryWrapper<DocCollaborations> collaborationsLambdaQueryWrapper = new LambdaQueryWrapper<>();
            collaborationsLambdaQueryWrapper.eq(DocCollaborations::getFileId, id);
            Page<DocCollaborations> docCollaborationsPage = new Page(page, pageSize);
            Page<DocCollaborations> docCollaborationsPage1 = docCollaborationsMapper.selectPage(docCollaborationsPage, collaborationsLambdaQueryWrapper);
            List<DocCollaborations> records = docCollaborationsPage1.getRecords();
            //获取名字

            List<DocumentUserDTO> list = records.stream().map(documentUserDTO -> {
                SysCompanyUserDTO data = userFeign.findUserById(documentUserDTO.getCollaborationId()).getData();
                DocumentUserDTO documentUserDTO1 = new DocumentUserDTO();
                documentUserDTO1.setId(documentUserDTO.getCollaborationId());
                documentUserDTO1.setUserName(data.getUserName());
                return documentUserDTO1;
            }).collect(Collectors.toList());

            documentUserDTOPageResult.setRows(list);
            documentUserDTOPageResult.setTotalPage(docCollaborationsPage1.getPages());
            documentUserDTOPageResult.setTotal(docCollaborationsPage1.getTotal());
            return documentUserDTOPageResult;

        } else {
            LambdaQueryWrapper<DocCollaborations> collaborationsLambdaQueryWrapper = new LambdaQueryWrapper<>();
            collaborationsLambdaQueryWrapper.eq(DocCollaborations::getFileId, id);
            List<DocCollaborations> docCollaborations = docCollaborationsMapper.selectList(collaborationsLambdaQueryWrapper);

            List<DocumentUserDTO> list = docCollaborations.stream().map(documentUserDTO -> {
                SysCompanyUserDTO data = userFeign.findUserById(documentUserDTO.getCollaborationId()).getData();
                DocumentUserDTO documentUserDTO1 = new DocumentUserDTO();
                documentUserDTO1.setId(documentUserDTO.getCollaborationId());
                documentUserDTO1.setUserName(data.getUserName());
                return documentUserDTO1;
            }).collect(Collectors.toList());

            documentUserDTOPageResult.setRows(list);
            return documentUserDTOPageResult;
        }


    }

    @Override
    public void deleteUser(DocCollaborationsDto docCollaborationsDto) {
        if (docCollaborationsDto == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        LambdaQueryWrapper<DocCollaborations> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(DocCollaborations::getFileId, docCollaborationsDto.getFileId());
        lambdaQueryWrapper.eq(DocCollaborations::getCollaborationId, docCollaborationsDto.getUserId());
        docCollaborationsMapper.delete(lambdaQueryWrapper);
    }

    @Override
    public List<DocUserCollaborationDTO> getUserList(Long fileId) {

        //查询拥有者ID
        DocFile docFile = docFileMapper.selectById(fileId);
        Long createUserId = docFile.getCreateUserId();
        if (createUserId == null) {
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }
        //查询协作者ID
        LambdaQueryWrapper<DocCollaborations> docCollaborationsLambdaQueryWrapper = new LambdaQueryWrapper<>();
        docCollaborationsLambdaQueryWrapper.eq(DocCollaborations::getFileId, fileId);
        List<DocCollaborations> doclist = docCollaborationsMapper.selectList(docCollaborationsLambdaQueryWrapper);
        List<Long> colist = new ArrayList();
        for (DocCollaborations docCollaborations : doclist) {
            Long collaborationId = docCollaborations.getCollaborationId();
            colist.add(collaborationId);
        }
        //查询所有员工
        List<SysCompanyUserDTO> userDTOList = userFeign.findAllCompanyUser().getData();
        List<DocUserCollaborationDTO> resultList = new ArrayList();
        for (SysCompanyUserDTO companyUserDTO : userDTOList) {
            DocUserCollaborationDTO docUserCollaborationDTO = new DocUserCollaborationDTO();
            docUserCollaborationDTO.setId(companyUserDTO.getId());
            docUserCollaborationDTO.setImgUrl(companyUserDTO.getImageUrl());
            docUserCollaborationDTO.setPhone(companyUserDTO.getMobile());
            docUserCollaborationDTO.setUsername(companyUserDTO.getUserName());
            if (companyUserDTO.getId() == createUserId) {
                docUserCollaborationDTO.setState(1);
                resultList.add(docUserCollaborationDTO);
            } else {
                if (colist.size() == 0) {
                    docUserCollaborationDTO.setState(0);
                    resultList.add(docUserCollaborationDTO);
                } else {
                    if (colist.contains(companyUserDTO.getId())) {
                        docUserCollaborationDTO.setState(2);
                        resultList.add(docUserCollaborationDTO);
                    } else {
                        docUserCollaborationDTO.setState(0);
                        resultList.add(docUserCollaborationDTO);
                    }
                }
            }
        }
        return resultList;
    }

    @Override
    public void insertCollaboration(DocCollaborationsDto docCollaborationsDto) {
        DocCollaborations docCollaborations = new DocCollaborations();
        docCollaborations.setFileId(docCollaborationsDto.getFileId());
        docCollaborations.setCollaborationId(docCollaborationsDto.getUserId());
        collaborationsMapper.insert(docCollaborations);
    }


    @Autowired
    DocFileMapper docFileMapper;

    @Autowired
    DocCollaborationsMapper collaborationsMapper;

    @Autowired
    SysUserFeign userFeign;

    private List<DocFileDto> queryFileList(Long parentFolderId) {
        Long companyId = CurrentUserHolder.get().getCompanyId();
        Long companyUserId = CurrentUserHolder.get().getCompanyUserId();
        //1. 查询可以公共读/公共读写的文件
        LambdaQueryWrapper<DocFile> docFileQw1 = new LambdaQueryWrapper<>();
        docFileQw1.eq(DocFile::getCompanyId, companyId);
        docFileQw1.eq(DocFile::getFolderId, parentFolderId);
        docFileQw1.eq(DocFile::getStatus, 1);
        docFileQw1.in(DocFile::getPermission, DocumentPermissionEnum.ALL_READ.getPermission(), DocumentPermissionEnum.ALL_READ_WRITE.getPermission());


        List<DocFile> docFileList1 = docFileMapper.selectList(docFileQw1);

        //2. 查询私有的文件(自己创建的文件)
        LambdaQueryWrapper<DocFile> docFileQw2 = new LambdaQueryWrapper<>();
        docFileQw2.eq(DocFile::getCompanyId, companyId);
        docFileQw2.eq(DocFile::getFolderId, parentFolderId);
        docFileQw2.eq(DocFile::getStatus, 1);
        docFileQw2.eq(DocFile::getPermission, DocumentPermissionEnum.PRIVATE_READ_WRITE.getPermission());
        docFileQw2.eq(DocFile::getCreateUserId, companyUserId); // 本人id

        List<DocFile> docFileList2 = docFileMapper.selectList(docFileQw2);

        //3. 查询自己为协作者关联的文件
        List<DocFile> docFileList3 = null;
        //查询自己为协作者 关联的文件的id
        LambdaQueryWrapper<DocCollaborations> docCollaborationsQw = new LambdaQueryWrapper<>();
        docCollaborationsQw.eq(DocCollaborations::getCollaborationId, companyUserId);
        //协作者 集合数据
        List<DocCollaborations> collaborationsList = collaborationsMapper.selectList(docCollaborationsQw);
        //如果协作者 列表不为null ， 则取出 文件id
        if (CollectionUtil.isNotEmpty(collaborationsList)) {
            List<Long> fileIds = collaborationsList.stream().map(docCollaborations -> {
                return docCollaborations.getFileId();
            }).collect(Collectors.toList());

            LambdaQueryWrapper<DocFile> docFileQw3 = new LambdaQueryWrapper<>();

            docFileQw3.eq(DocFile::getCompanyId, companyId);
            docFileQw3.eq(DocFile::getFolderId, parentFolderId);
            docFileQw3.eq(DocFile::getStatus, 1);
            docFileQw3.in(DocFile::getId, fileIds);

            docFileList3 = docFileMapper.selectList(docFileQw3);

        }


        //组装文件集合
        List<DocFile> docFileList = new ArrayList<>();
        docFileList.addAll(docFileList1);
        docFileList.addAll(docFileList2);
        docFileList.addAll(docFileList3);

        //去重
        docFileList = CollectionUtil.distinct(docFileList);


        // 转换数据集合
        List<DocFileDto> docFileDtoList = BeanHelper.copyWithCollection(docFileList, DocFileDto.class);

        for (DocFileDto docFileDto : docFileDtoList) {
            //查询创建者用户名
            SysCompanyUserDTO companyUserDTOCreate = userFeign.findUserById(docFileDto.getCreateUserId()).getData();

            docFileDto.setUserName(companyUserDTOCreate.getUserName());
            //查询更新着用户名
            SysCompanyUserDTO companyUserDTOUpdate = userFeign.findUserById(docFileDto.getUpdateUserId()).getData();
            if (companyUserDTOUpdate != null) {
                docFileDto.setUpdateUserName(companyUserDTOUpdate.getUserName());
            }
        }

        return docFileDtoList;
    }

    @Autowired
    DocFolderMapper folderMapper;

    private List<DocFolderDto> queryFolderList(Long parentFolderId) {
        LambdaQueryWrapper<DocFolder> docFolderQw = new LambdaQueryWrapper<>();
        docFolderQw.eq(DocFolder::getParentId, parentFolderId);
        docFolderQw.eq(DocFolder::getCompanyId, CurrentUserHolder.get().getCompanyId());
        docFolderQw.eq(DocFolder::getStatus, 1);
        List<DocFolder> docFolderList = folderMapper.selectList(docFolderQw);
        if (docFolderList != null) {
            List<DocFolderDto> docFolderDtos = BeanHelper.copyWithCollection(docFolderList, DocFolderDto.class);
            return docFolderDtos;
        }

        return new ArrayList<>();
    }
}
